package cn.bfay.lion.jingdong.service.impl;

import cn.bfay.cache.redis.RedisKeyBuilder;
import cn.bfay.cache.redis.RedisTime;
import cn.bfay.cache.redis.RedisUtils;
import cn.bfay.lion.jingdong.client.rsp.JdProductInfo;
import cn.bfay.lion.jingdong.entity.ProductDetailInfo;
import cn.bfay.lion.jingdong.entity.ProductInfo;
import cn.bfay.lion.jingdong.error.BusinessError;
import cn.bfay.lion.jingdong.mapper.ProductDetailInfoMapper;
import cn.bfay.lion.jingdong.mapper.ProductInfoMapper;
import cn.bfay.lion.jingdong.redis.RedisKeyTemplate;
import cn.bfay.lion.jingdong.service.AbstractService;
import cn.bfay.lion.jingdong.service.ProductInfoService;
import cn.bfay.lion.jingdong.vo.ProductInfoVo;
import cn.bfay.web.exception.BizException;
import cn.bfay.web.result.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Splitter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * MESSAGE.
 *
 * @author wangjiannan
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ProductInfoServiceImpl extends AbstractService implements ProductInfoService {
    private final ProductInfoMapper productInfoMapper;
    private final ProductDetailInfoMapper productDetailInfoMapper;

    @Override
    public void addProductBySkuid(String skuid) {
        ProductInfo oldProductInfo = productInfoMapper.selectOne(new QueryWrapper<ProductInfo>().lambda()
            .eq(ProductInfo::getSkuid, skuid));
        if (oldProductInfo != null) {
            return;
        }

        JdProductInfo jdProductInfo = crawlJdProductInfo(skuid);
        if (jdProductInfo.getName() == null || jdProductInfo.getNormalPrice() == null) {
            throw new BizException(BusinessError.PRODUCT_ADD_ERROR);
        }
        // 商品下架，无需考虑优惠
        if (jdProductInfo.getNormalPrice() <= 0) {
            throw new BizException(BusinessError.PRODUCT_SOLD_OUT);
        }

        ProductDetailInfo productDetailInfo = new ProductDetailInfo();
        BeanUtils.copyProperties(jdProductInfo, productDetailInfo);
        productDetailInfoMapper.insert(productDetailInfo);

        ProductInfo productInfo = new ProductInfo();
        BeanUtils.copyProperties(jdProductInfo, productInfo);
        productInfo.setProductDetailInfoId(productDetailInfo.getId());
        productInfoMapper.insert(productInfo);
        // 设置商品最新的信息缓存
        RedisUtils.setValue(RedisKeyBuilder.generateRedisKey(RedisKeyTemplate.PRODUCT_DETAIL_INFO_TEMPLATE, skuid),
            productDetailInfo, RedisTime.MONTH);
    }

    @Override
    public ProductInfoVo getProductBySkuid(String skuid) {
        ProductInfo productInfo = productInfoMapper.selectOne(new QueryWrapper<ProductInfo>().lambda()
            .eq(ProductInfo::getSkuid, skuid));
        if (productInfo == null) {
            throw new BizException(BusinessError.PRODUCT_NOT_EXIST);
        }
        if (productInfo.getValid() == 0) {
            throw new BizException(BusinessError.PRODUCT_NOT_SUPPORT);
        }

        ProductInfoVo productInfoVo = new ProductInfoVo();
        BeanUtils.copyProperties(productInfo, productInfoVo);
        return productInfoVo;
    }

    @Override
    public List<ProductInfoVo> getProductBySkuids(String skuids) {
        List<String> skuidList = Splitter.on(",").splitToList(skuids);
        List<ProductInfo> productInfos = productInfoMapper.selectList(new QueryWrapper<ProductInfo>().lambda()
            .in(ProductInfo::getSkuid, skuidList));
        if (CollectionUtils.isEmpty(productInfos)) {
            throw new BizException(BusinessError.PRODUCT_NOT_EXIST);
        }
        List<ProductInfoVo> productInfoVos = new ArrayList<>(productInfos.size());
        productInfos.forEach(productInfo -> {
            ProductInfoVo productInfoVo = new ProductInfoVo();
            BeanUtils.copyProperties(productInfo, productInfoVo);
            productInfoVos.add(productInfoVo);
        });
        return productInfoVos;
    }

    @Override
    public PageResult<ProductInfoVo> getProductByPaging(String name, Long pageNum, Long pageSize) {
        Page<ProductInfo> page = new Page<>(pageNum, pageSize);
        page.addOrder(OrderItem.desc("update_time"));
        IPage<ProductInfo> iPage = productInfoMapper.selectPage(page, new QueryWrapper<ProductInfo>().lambda()
            .like(ProductInfo::getName, name));
        return new PageResult<>(iPage.getCurrent(), iPage.getSize(), iPage.getPages(),
            iPage.getTotal(), iPage.getRecords(), ProductInfoVo.class);
    }
}
